【翻訳】Dependency Injection 入門
You're in the car business, your job is to make cars on-demand. The object-oriented programmer in you says: "no problem, I'll make a blueprint that I can use to make as many cars as I want!".
あなたは自動車業界にいて、仕事は自動車をオンデマンドで販売することです。
あなたの中のオブジェクト指向プログラマーが言います。
「問題ありません、私が欲しい多くの車を作るため青写真を作るつもりです!」
code:php
class Car
{
public function drive()
{
// ...
}
}
For this car to work, it needs an engine and wheels. Now, there are several approaches to achieve that goal. You could, for example, do the following:
この車が機能するには、エンジンと車輪が必要です。
今、その目標を達成するためのいくつかのアプローチがあります。たとえば、次のようにします。
code:php
class Car
{
public function __construct()
{
$this->engine = new Engine();
$this->wheels = [
new Wheel(), new Wheel(),
new Wheel(), new Wheel(),
];
}
public function drive() { ... }
}
There's the blueprint for every car you'll make! Next up, your boss comes to you and says there's a new client and he wants an electric car.
すべての車を作れる青写真ができました!
次に、あなたの上司があなたのところに来て、「新しいクライアントがいる。彼は電気自動車を望んでいる」と言います。
So you end up doing this.
だからあなたはこれをやってしまう。
code:php
class ElectricCar extends Car
{
public function __construct()
{
parent::__construct();
$this->engine = new ElectricEngine();
}
}
"Beautifully solved"—you think. There's of course that redundant normal engine that's created when calling parent::__construct(), but at least you could re-use the wheels!
「美しく実装できたじゃないか」っとあなたは思います。
もちろん、parent :: __ construct()を呼び出すときに作成される冗長なエンジンがありますが、少なくともホイールは再利用できます
I think you can see where this is going. The next client wants a car with some fancy wheel covers, another one would like a diesel engine with those same wheel covers, another one requests a race car, and the last one wants a self driving car.
Oh—there also was a client who wanted to buy an engine to build a boat with himself, but you told your boss that wouldn't be possible.
他にもこれと同様のケースを見る事ができると思います。次の顧客は、いくつかの高級ホイールカバー付きの車を望み、別の顧客は同じホイールカバー付きのディーゼルエンジンを望み、別の顧客はレースカーを要求し、最後の顧客は自走車を望みます。
ああ - 自分でボートを建造するためにエンジンを購入したいというクライアントもいましたが、あなたは不可能だとあなたの上司に言いました。
After a while, there's a ton of blueprints in your office, each describing a very specific variation of a car. You started with a neatly ordered pile of blueprints. But after a while you had to group them in different folders and boxes, because it was taking too long to find the blueprint you're looking for.
しばらくすると、あなたのオフィスに山程の青写真ができ、それぞれは車の非常に特定の変化を説明します。
あなたはきれいに整えられた青写真の山から始めました。 しかししばらくすると、探している青写真を見つけるのに時間がかかりすぎたため、それらを異なるフォルダやボックスにグループ化する必要がありました。
Object oriented programmers often fall into this trap of inheritance, ending in a completely messed up codebase. So let's look at a better approach. Maybe you've heard about "composition over inheritance" before?
オブジェクト指向プログラマはしばしばこの継承の罠に陥り、完全に混乱したコードベースになってしまいます。
それではもっと良いアプローチを見てみましょう。
あなたは以前に"composition over inheritance"(継承よりも合成)について聞いたことがありますか?
Composition over inheritance is the principle that classes should achieve polymorphic behavior and code reuse by their composition rather than inheritance from a base or parent class—Wikipedia
Composition over inheritanceとは、基本クラスや親クラスからの継承ではなく、構成によって多態的な振る舞いとコードの再利用を実現するという原則です - Wikipedia
That's a lot of buzzwords. Let's just look at our car example. The principle states that Car should achieve its polymorphic behaviour by being composed of other classes.
Composition over inheritanceはバズワードです。
私たちの車の例を見てみましょう。 その原則は、Carが他のクラスから構成されることによってその多形的振る舞いを達成するべきであると述べています。
The word polymorphic literally means "many shapes" and implies that Car should be able to do drive in many different ways, depending on the context it's used in.
ポリモフィックという言葉は文字通り「多くの形」を意味し、Carはその中で使われている文脈に応じて、さまざまな方法で運転できるはずであることを意味します。
With code reuse, we're trying to make code reusable; so that we don't end up with tens of classes doing almost exectly the same.
コードを再利用することで、コードを再利用可能にしようとしています。それで、私たちが数十のクラスでほとんど同じように同じことをしないようにしましょう。
What does this have to do with dependency injection
Instead of making a unique blueprint that describes every single possible variation of a car, we'd rather have Car do one thing, and do it good: drive.
車のすべて設計可能なバリエーションできる独自の青写真を作成する代わりに、むしろCarに1つのことをさせて、それをうまくやらせて、良いドライブを楽しみましょう[]
This means it shouldn't be the car's concern how its engine is built, what wheels it has attached. It should only know the following thing:Given a working engine and four wheels, I'm able to drive!
We could say that in order for Car to work, it needs an engine and wheels. In other words: Car depends on Engine and a collection of Wheels.
Those dependencies should be given to the car. Or, said otherwise: injected.